package com.lixl.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AioTcpServer {
	private AsynchronousServerSocketChannel listener;
	private ExecutorService executor = Executors.newFixedThreadPool(20);

	public AioTcpServer(int port) throws Exception {
		AsynchronousChannelGroup asyncChannelGroup = AsynchronousChannelGroup
				.withThreadPool(executor);
		listener = AsynchronousServerSocketChannel.open(asyncChannelGroup)
				.bind(new InetSocketAddress(port));
	}

	public void start() {
		listener.accept(listener,
				new AioTcpServer.AsynchronousServerCompletionHandler());
	}

	public void shutdown() {
		executor.shutdown();
	}

	static class AsynchronousServerCompletionHandler
			implements
			CompletionHandler<AsynchronousSocketChannel, AsynchronousServerSocketChannel> {

		@Override
		public void failed(Throwable exc,
				AsynchronousServerSocketChannel attachment) {
			exc.printStackTrace();
		}

		@Override
		public void completed(AsynchronousSocketChannel result,
				AsynchronousServerSocketChannel attachment) {
			try {
				System.out.println("有客户端连接:"
						+ result.getRemoteAddress().toString());
			} catch (IOException e) {
				e.printStackTrace();
			}

			ByteBuffer clientBuffer = ByteBuffer.allocate(1024);
			result.read(clientBuffer, clientBuffer,
					new AioTcpServer.ByteBufferCompletionHandler());
			try {
				result.close();
				attachment.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	static class ByteBufferCompletionHandler implements
			CompletionHandler<Integer, ByteBuffer> {
		@Override
		public void completed(Integer i, ByteBuffer buf) {
			if (i > 0) {
				buf.flip();
				try {
					System.out.println(Charset.forName("GBK").newDecoder()
							.decode(buf));
					buf.compact();
				} catch (CharacterCodingException e) {
					e.printStackTrace();
				}
			}
		}

		@Override
		public void failed(Throwable exc, ByteBuffer attachment) {
			exc.printStackTrace();
		}

	}

	public static void main(String[] args) throws Exception {
		int port = 8080;
		AioTcpServer server = new AioTcpServer(port);
		server.start();
		System.out.println("port:" + port);
		System.out.println("Server started success~ 输入任意字符停止");
		System.in.read();
		server.shutdown();
		System.out.println("Server stoped success~");
	}

}
